package gmail;

import java.util.ArrayList;
/**
 * various helper class
 * @author siuying
 * @version 0.3.3 
 */
public class Utilities 
{
    
  /**
   * Parse a java script array to nested array list in Java
   * @param input String
   * @return ArrayList
   */
  public static ArrayList ParseJSArray(String input) {
    Integer[] outReturnOffset = {new Integer(0)};
    return ParseJSArrayRecurse(input, outReturnOffset);
  }

  private static ArrayList ParseJSArrayRecurse(String input, Integer[] outReturnOffset) {
      // instantiate output
      ArrayList output = new ArrayList();

      // state variables
      boolean isQuoted = false;		// track when we are inside quotes
      String dataHold = "";		// temporary data container
      char lastCharacter = ' ';

      // loop through the entire string
      for(int i=1; i < input.length(); i++) {
          switch(input.charAt(i)) {
              case '[':	// handle start of array marker
                  if(!isQuoted) {
                          // recurse any nested arrays
                          output.add(ParseJSArrayRecurse(input.substring(i), outReturnOffset));

                          // the returning recursive function write out the total length of the characters consumed
                          i += outReturnOffset[0].intValue();

                          // assume that the last character is a closing bracket
                          lastCharacter = ']';
                  } else {
                          dataHold += "[";
                  }
                  break;

              case ']':	// handle end of array marker
                  if(!isQuoted) {
                          if(dataHold != "") {
                                  output.add(dataHold);
                          }

                          // determine total number of characters consumed (write to reference)
                          outReturnOffset[0] = new Integer(i);
                          return output;
                  } else {
                          dataHold += "]";
                          break;
                  }

              case '"':	// toggle quoted state
                  if(isQuoted) {
                          isQuoted = false;
                  } else {
                          isQuoted = true;
                          lastCharacter = '"';
                  }
                  break;
                  
              case ',':	// find end of element marker and add to array
                  if(!isQuoted) {
                          if(dataHold != "") {	// this is to filter out adding extra elements after an empty array
                                  output.add(dataHold);
                                  dataHold = "";
                          } else if(lastCharacter == '"') {	// this is to catch empty strings
                                  output.add("");
                          }
                  } else {
                          dataHold += ",";
                  }
                  break;
              case '\\':
                  // handle escape characters
                  if(i < input.length() - 1) {
                      switch (input.charAt(i+1)){  
                          case '\'':                          
                            dataHold += '\'';
                            i++;                            
                            break;
                          case '"':
                            dataHold += '"';
                            i++;                            
                            break;
                          case '<':
                            dataHold += '<';
                            i++;                            
                            break;
                          case '>':
                            dataHold += '>';
                            i++;                            
                            break;
                          case '\\':
                            dataHold += '\\';
                            i++;
                            break;
                          case 'r':
                            dataHold += '\r';
                            i++;
                            break;
                          case 'n':
                            dataHold += '\n';
                            i++;                            
                            // lastCharacter = '\\';
                            break;                            
                      }
                  }
                  break;

              default:	// regular characters are added to the data container
                  dataHold += input.charAt(i);
                  break;
          }
        }

        return output;
    }

}
